﻿Imports Infragistics.Windows.Editors
Imports System.Windows.Input
Imports System.Globalization
Imports System.Windows
Imports System.Windows.Controls

Public Class NumericEditor
    Inherits XamNumericEditor

    'Private textBox As TextBox
    'Public Overrides Sub OnApplyTemplate()
    '    FormatProvider = New System.Globalization.CultureInfo("fr-FR")
    '    MyBase.OnApplyTemplate()
    '    FormatProvider = New System.Globalization.CultureInfo("fr-FR")
    'End Sub

    Public Property MaxValue As Double
        Get
            If ValueConstraint Is Nothing Then
                Return Double.MaxValue
            Else
                If Not ValueConstraint.HasMaxExclusive And Not ValueConstraint.HasMaxInclusive Then
                    Return Double.MaxValue
                Else
                    If ValueConstraint.HasMaxExclusive Then
                        Return ValueConstraint.HasMaxExclusive
                    End If
                    If ValueConstraint.HasMaxInclusive Then
                        Return ValueConstraint.HasMaxInclusive
                    End If
                End If
            End If
            Return Double.MaxValue
        End Get
        Set(ByVal value As Double)
            If Me.ValueConstraint Is Nothing Then
                Me.ValueConstraint = New ValueConstraint() With {.MaxInclusive = value, .Nullable = False, .ValidateAsType = ValidateAsType.Double}
            Else
                If ValueConstraint.HasMaxInclusive Then
                    Me.ValueConstraint.MaxInclusive = value
                Else
                    If ValueConstraint.HasMaxExclusive Then
                        Me.ValueConstraint.MaxExclusive = value
                    Else
                        Me.ValueConstraint.MaxInclusive = value
                    End If
                End If
            End If
        End Set
    End Property

    Sub New()
        MyBase.New()
        FormatProvider = New System.Globalization.CultureInfo("fr-FR")
        Language = Markup.XmlLanguage.GetLanguage("fr-FR")
    End Sub

    Private _plusButtonCommand As ICommand = New SpinButtonClickCommand() With {.method = AddressOf PlusExecute}
    Public ReadOnly Property PlusButtonCommand As ICommand
        Get
            Return _plusButtonCommand
        End Get
    End Property
    Private _moinsButtonCommand As ICommand = New SpinButtonClickCommand() With {.method = AddressOf MoinsExecute}
    Public ReadOnly Property MoinsButtonCommand As ICommand
        Get
            Return _moinsButtonCommand
        End Get
    End Property
    Private Sub MoinsExecute(ByVal parameter As Object)
        Try
            Dim temp = Value - Convert.ChangeType(SpinIncrement, Value.GetType(), CultureInfo.CurrentCulture)
            If ValueConstraint Is Nothing Then
                Value = temp
                Return
            End If
            Dim min = If(ValueConstraint.HasMinInclusive, ValueConstraint.MinInclusive, _
                    If(ValueConstraint.HasMinExclusive, ValueConstraint.MinExclusive, Nothing))
            If min IsNot Nothing Then
                temp = Math.Max(Convert.ChangeType(min, Value.GetType(), CultureInfo.CurrentCulture), temp)
            End If
            Dim max = If(ValueConstraint.HasMaxInclusive, ValueConstraint.MaxInclusive, _
                    If(ValueConstraint.HasMaxExclusive, ValueConstraint.MaxExclusive, Nothing))
            If max IsNot Nothing Then
                temp = Math.Min(Convert.ChangeType(max, Value.GetType(), CultureInfo.CurrentCulture), temp)
            End If
            Value = temp
        Catch ex As Exception
            Try
                Dim temp = Value - Convert.ChangeType(SpinIncrement, Value.GetType(), CultureInfo.InvariantCulture)
                If ValueConstraint Is Nothing Then
                    Value = temp
                    Return
                End If
                Dim min = If(ValueConstraint.HasMinInclusive, ValueConstraint.MinInclusive, _
                             If(ValueConstraint.HasMinExclusive, ValueConstraint.MinExclusive, Nothing))
                If min IsNot Nothing Then
                    temp = Math.Max(Convert.ChangeType(min, Value.GetType(), CultureInfo.InvariantCulture), temp)
                End If
                Dim max = If(ValueConstraint.HasMaxInclusive, ValueConstraint.MaxInclusive, _
                        If(ValueConstraint.HasMaxExclusive, ValueConstraint.MaxExclusive, Nothing))
                If max IsNot Nothing Then
                    temp = Math.Min(Convert.ChangeType(max, Value.GetType(), CultureInfo.InvariantCulture), temp)
                End If
                Value = temp
            Catch ex1 As Exception
                Try
                    Dim temp = Value - Convert.ChangeType(SpinIncrement, Value.GetType(), CultureInfo.InstalledUICulture)
                    If ValueConstraint Is Nothing Then
                        Value = temp
                        Return
                    End If
                    Dim min = If(ValueConstraint.HasMinInclusive, ValueConstraint.MinInclusive, _
                        If(ValueConstraint.HasMinExclusive, ValueConstraint.MinExclusive, Nothing))
                    If min IsNot Nothing Then
                        temp = Math.Max(Convert.ChangeType(min, Value.GetType(), CultureInfo.InstalledUICulture), temp)
                    End If
                    Dim max = If(ValueConstraint.HasMaxInclusive, ValueConstraint.MaxInclusive, _
                            If(ValueConstraint.HasMaxExclusive, ValueConstraint.MaxExclusive, Nothing))
                    If max IsNot Nothing Then
                        temp = Math.Min(Convert.ChangeType(max, Value.GetType(), CultureInfo.InstalledUICulture), temp)
                    End If
                    Value = temp
                Catch ex2 As Exception

                End Try
            End Try
        End Try
    End Sub
    Private Sub PlusExecute(ByVal parameter As Object)
        Try
            Dim temp = Value + Convert.ChangeType(SpinIncrement, Value.GetType(), CultureInfo.CurrentCulture)
            If ValueConstraint Is Nothing Then
                Value = temp
                Return
            End If
            Dim min = If(ValueConstraint.HasMinInclusive, ValueConstraint.MinInclusive, _
                    If(ValueConstraint.HasMinExclusive, ValueConstraint.MinExclusive, Nothing))
            If min IsNot Nothing Then
                temp = Math.Max(Convert.ChangeType(min, Value.GetType(), CultureInfo.CurrentCulture), temp)
            End If
            Dim max = If(ValueConstraint.HasMaxInclusive, ValueConstraint.MaxInclusive, _
                    If(ValueConstraint.HasMaxExclusive, ValueConstraint.MaxExclusive, Nothing))
            If max IsNot Nothing Then
                temp = Math.Min(Convert.ChangeType(max, Value.GetType(), CultureInfo.CurrentCulture), temp)
            End If
            Value = temp
        Catch ex As Exception
            Try
                Dim temp = Value + Convert.ChangeType(SpinIncrement, Value.GetType(), CultureInfo.InvariantCulture)
                If ValueConstraint Is Nothing Then
                    Value = temp
                    Return
                End If
                Dim min = If(ValueConstraint.HasMinInclusive, ValueConstraint.MinInclusive, _
                             If(ValueConstraint.HasMinExclusive, ValueConstraint.MinExclusive, Nothing))
                If min IsNot Nothing Then
                    temp = Math.Max(Convert.ChangeType(min, Value.GetType(), CultureInfo.InvariantCulture), temp)
                End If
                Dim max = If(ValueConstraint.HasMaxInclusive, ValueConstraint.MaxInclusive, _
                        If(ValueConstraint.HasMaxExclusive, ValueConstraint.MaxExclusive, Nothing))
                If max IsNot Nothing Then
                    temp = Math.Min(Convert.ChangeType(max, Value.GetType(), CultureInfo.InvariantCulture), temp)
                End If
                Value = temp
            Catch ex1 As Exception
                Try
                    Dim temp = Value + Convert.ChangeType(SpinIncrement, Value.GetType(), CultureInfo.InstalledUICulture)
                    If ValueConstraint Is Nothing Then
                        Value = temp
                        Return
                    End If
                    Dim min = If(ValueConstraint.HasMinInclusive, ValueConstraint.MinInclusive, _
                        If(ValueConstraint.HasMinExclusive, ValueConstraint.MinExclusive, Nothing))
                    If min IsNot Nothing Then
                        temp = Math.Max(Convert.ChangeType(min, Value.GetType(), CultureInfo.InstalledUICulture), temp)
                    End If
                    Dim max = If(ValueConstraint.HasMaxInclusive, ValueConstraint.MaxInclusive, _
                            If(ValueConstraint.HasMaxExclusive, ValueConstraint.MaxExclusive, Nothing))
                    If max IsNot Nothing Then
                        temp = Math.Min(Convert.ChangeType(max, Value.GetType(), CultureInfo.InstalledUICulture), temp)
                    End If
                    Value = temp
                Catch ex2 As Exception

                End Try
            End Try
        End Try
    End Sub
    Private Class SpinButtonClickCommand
        Implements ICommand

        Friend method As Action(Of Object)
        Private Event CanExecuteChanged(ByVal sender As Object, ByVal e As System.EventArgs) Implements System.Windows.Input.ICommand.CanExecuteChanged
        Private Function CanExecute(ByVal parameter As Object) As Boolean Implements System.Windows.Input.ICommand.CanExecute
            Return True
        End Function
        Private Sub Execute(ByVal parameter As Object) Implements System.Windows.Input.ICommand.Execute
            method(parameter)
        End Sub


    End Class

End Class
Public Class IncDecCommand
    Inherits DependencyObject
    Implements ICommand



    Public Property TargetValue As Integer
        Get
            Return GetValue(TargetValueProperty)
        End Get

        Set(ByVal value As Integer)
            SetValue(TargetValueProperty, value)
        End Set
    End Property

    Public Shared ReadOnly TargetValueProperty As DependencyProperty = _
                           DependencyProperty.Register("TargetValue", _
                           GetType(Integer), GetType(IncDecCommand), _
                           New FrameworkPropertyMetadata(Nothing))


    Public Function CanExecute(ByVal parameter As Object) As Boolean Implements System.Windows.Input.ICommand.CanExecute
        Return True
    End Function

    Public Event CanExecuteChanged(ByVal sender As Object, ByVal e As System.EventArgs) Implements System.Windows.Input.ICommand.CanExecuteChanged

    Public Sub Execute(ByVal parameter As Object) Implements System.Windows.Input.ICommand.Execute
        Dim op As String = If(String.IsNullOrEmpty(parameter), "inc", "dec")
        If op = "inc" Then
            TargetValue += 1
        End If
        If op = "dec" Then
            TargetValue -= 1
        End If
    End Sub
End Class
Public Class NumericTextbox
    Inherits TextBox

    Dim previous As String

    Public Shared Sub DoTheRightThing(ByVal target As Object)
        Dim t As NumericEditor = TryCast(target, NumericEditor)
        If t IsNot Nothing Then
            t.ValidateCurrentValue()
            If Not t.IsValueValid Then
                t.EndEditMode(False, False)
            Else
                t.EndEditMode(True, False)
            End If
        Else
            Dim t1 As NumericTextbox = TryCast(target, NumericTextbox)

            If t1 IsNot Nothing Then
                '   Dim p = TryCast(t1.FindCommonVisualAncestor(t1.TemplatedParent), NumericEditor)
                Dim p = TryCast(t1.TemplatedParent, NumericEditor)
                p.ValidateCurrentValue()
                If Not p.IsValueValid Then
                    p.EndEditMode(False, False)
                Else
                    p.EndEditMode(True, False)
                End If

            End If
        End If
    End Sub

    Protected Overrides Sub OnKeyDown(ByVal e As System.Windows.Input.KeyEventArgs)
        'Dim s = (New KeyGesture(e.Key, e.KeyboardDevice.Modifiers)).GetDisplayStringForCulture(CultureInfo.CurrentUICulture)

        If e.Key = Key.Return Or e.Key = Key.Escape Then
            MyBase.OnKeyDown(e)
            Return
        End If
        If e.Key.ToString().StartsWith("D") Then
            If e.Key <> Key.D Then

                If Char.IsNumber(e.Key.ToString()(1)) Then
                    Dim pre = Me.CaretIndex
                    Me.Text = Me.Text.Insert(Me.CaretIndex, e.Key.ToString()(1))
                    Me.CaretIndex = pre + 1
                    'MyBase.OnKeyDown(e)
                    'Return
                End If
            End If
        End If

        If e.Key = Key.OemComma Then

            If Not Me.Text.Contains(",") Then
                Dim pre = Me.CaretIndex
                Me.Text = Me.Text.Insert(Me.CaretIndex, ",")
                Me.CaretIndex = pre + 1
            End If
            'MyBase.OnKeyDown(e)
            'Return
        End If

        If e.Key.ToString().StartsWith("NumPad") Then
            MyBase.OnKeyDown(e)
            Return
        End If

        e.Handled = True
    End Sub
End Class